Header file optional.hpp

namespace type_safe
{
    //=== Basic optional ===//
    struct nullopt_t;
    
    constexpr nullopt_t nullopt;
    
    template <typename T>
    struct optional_storage_policy_for;
    
    template <class StoragePolicy>
    struct optional_storage_policy_for<basic_optional<StoragePolicy>>;
    
    template <typename T>
    struct optional_storage_policy_for<T&>;
    
    template <typename T>
    struct optional_storage_policy_for<T&&>;
    
    template <class StoragePolicy>
    class basic_optional;
    
    template <class StoragePolicy>
    bool operator==(const basic_optional<StoragePolicy>& lhs, nullopt_t);
    
    template <class StoragePolicy>
    bool operator==(nullopt_t, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy>
    bool operator!=(const basic_optional<StoragePolicy>& lhs, nullopt_t);
    template <class StoragePolicy>
    bool operator!=(nullopt_t, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy>
    bool operator<(const basic_optional<StoragePolicy>& lhs, nullopt_t);
    template <class StoragePolicy>
    bool operator<(nullopt_t, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy>
    bool operator<=(const basic_optional<StoragePolicy>& lhs, nullopt_t);
    template <class StoragePolicy>
    bool operator<=(nullopt_t, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy>
    bool operator>(const basic_optional<StoragePolicy>& lhs, nullopt_t);
    template <class StoragePolicy>
    bool operator>(nullopt_t, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy>
    bool operator>=(const basic_optional<StoragePolicy>& lhs, nullopt_t);
    template <class StoragePolicy>
    bool operator>=(nullopt_t, const basic_optional<StoragePolicy>& rhs);
    
    //=== Optional value comparison ===//
    template <class StoragePolicy, typename U>
    bool operator==(const basic_optional<StoragePolicy>& lhs, const U& rhs);
    template <class StoragePolicy, typename U>
    bool                                                                       operator==(const U& lhs, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy, typename U>
    bool operator!=(const basic_optional<StoragePolicy>& lhs, const U& rhs);
    template <class StoragePolicy, typename U>
    bool                                                                       operator!=(const U& lhs, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy, typename U>
    bool operator<(const basic_optional<StoragePolicy>& lhs, const U& rhs);
    template <class StoragePolicy, typename U>
    bool                                                                       operator<(const U& lhs, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy, typename U>
    bool operator<=(const basic_optional<StoragePolicy>& lhs, const U& rhs);
    template <class StoragePolicy, typename U>
    bool                                                                       operator<=(const U& lhs, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy, typename U>
    bool operator>(const basic_optional<StoragePolicy>& lhs, const U& rhs);
    template <class StoragePolicy, typename U>
    bool                                                                       operator>(const U& lhs, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy, typename U>
    bool operator>=(const basic_optional<StoragePolicy>& lhs, const U& rhs);
    template <class StoragePolicy, typename U>
    bool                                                                       operator>=(const U& lhs, const basic_optional<StoragePolicy>& rhs);
    
    //=== Optional comparison ===//
    template <class StoragePolicy>
    bool operator==(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy>
    bool operator!=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy>
    bool operator<(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy>
    bool operator<=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy>
    bool operator>(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
    template <class StoragePolicy>
    bool operator>=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
    
    template <class Optional, typename Func, typename ... Args>
    void with(Optional&& opt, Func&& f, Args&&... additional_args);
    
    //=== Optional ===//
    template <typename T>
    class direct_optional_storage;
    
    template <typename T>
    using optional = basic_optional<direct_optional_storage<T>>;
    
    template <typename T>
    using optional_for = basic_optional<direct_optional_storage<int>>::rebind<T>;
    
    template <typename T>
    optional<typename std::decay<T>::type> make_optional(T&& t);
    
    template <typename T, typename ... Args>
    optional<T> make_optional(Args&&... args);
}

namespace std
{
}

Struct type_safe::nullopt_t [optional]

struct nullopt_t
{
    constexpr nullopt_t();
};

Tag type to mark a ts::basic_optional without a value.

Variable type_safe::nullopt [optional]

constexpr nullopt_t nullopt;

Tag object of type ts::nullopt_t.

Class template type_safe::optional_storage_policy_for [optional]

template <typename T>
struct optional_storage_policy_for
{
    using type = void;
};

Selects the storage policy used when rebinding a ts::basic_optional.

Some operations like ts::basic_optional::map() change the type of an optional. This traits controls which StoragePolicy is going to be used for the new optional. You can for example requests a ts::compact_optional_storage for your type, simply specialize it and set a type typedef.

Class template type_safe::optional_storage_policy_for<basic_optional<StoragePolicy>>

template <class StoragePolicy>
struct optional_storage_policy_for<basic_optional<StoragePolicy>>
{
    using type = StoragePolicy;
};

Specialization of ts::optional_storage_policy_for for ts::basic_optional itself.

It will simply forward to the same policy, so ts::optional_for<ts::optional<T>> is simply ts::optional<T>, not ts::optional<ts::optional<T>>. \module optional

Class template type_safe::optional_storage_policy_for<T&> [optional]

template <typename T>
struct optional_storage_policy_for<T&>
{
    using type = reference_optional_storage<T>;
};

Specialization of ts::optional_storage_policy_for for lvalue references.

It will use ts::reference_optional_storage as policy.

Class template type_safe::optional_storage_policy_for<T&&> [optional]

template <typename T>
struct optional_storage_policy_for<T&&>
{
};

Specialization of ts::optional_storage_policy_for for rvalue references.

They are not supported.

Class template type_safe::basic_optional [optional]

template <class StoragePolicy>
class basic_optional
{
public:
    using storage = StoragePolicy;
    
    using value_type = typename storage::value_type;
    
    template <typename U>
    using rebind = 'hidden';
    
    basic_optional() noexcept = default;
    basic_optional(nullopt_t) noexcept;
    
    template <typename T>
    basic_optional(T&& value);
    
    template <typename T>
    basic_optional(T&& value);
    
    basic_optional(const basic_optional& other) = default;
    
    basic_optional(basic_optional&& other) = default;
    
    ~basic_optional() noexcept = default;
    
    basic_optional& operator=(nullopt_t) noexcept;
    
    template <typename T>
    decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<T>(value)), *this) operator=(T&& value);
    
    basic_optional& operator=(const basic_optional& other) = default;
    
    basic_optional& operator=(basic_optional&& other) = default;
    
    friend void swap(basic_optional& a, basic_optional& b) noexcept('hidden');
    
    //=== Modifiers ===//
    void reset() noexcept;
    
    template <typename ... Args>
    decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<Args>(args)...)) emplace(Args&&... args) noexcept('hidden');
    
    template <typename Arg, typename = typename std::enable_if<detail::is_direct_assignable<decltype(std::declval<storage&>().get_value()), Arg&&>::value>::type>
    decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<Arg>(arg))) emplace(Arg&& arg) noexcept('hidden');
    
    //=== Observers ===//
    operator bool() const noexcept;
    
    bool has_value() const noexcept;
    
    decltype(std::declval<storage&>().get_value()) value() & noexcept;
    decltype(std::declval<const storage&>().get_value()) value() const & noexcept;
    decltype(std::declval<storage&&>().get_value()) value() && noexcept;
    decltype(std::declval<const storage&&>().get_value()) value() const && noexcept;
    
    template <typename U>
    decltype(std::declval<const storage&>().get_value_or(std::forward<U>(u))) value_or(U&& u) const &;
    
    template <typename U>
    decltype(std::declval<storage&&>().get_value_or(std::forward<U>(u))) value_or(U&& u) &&;
    
    template <typename Func, typename ... Args>
    'hidden' map(Func&& f, Args&&... args) &;
    template <typename Func, typename ... Args>
    'hidden' map(Func&& f, Args&&... args) const &;
    template <typename Func, typename ... Args>
    'hidden' map(Func&& f, Args&&... args) &&;
    template <typename Func, typename ... Args>
    'hidden' map(Func&& f, Args&&... args) const &&;
};

An optional type, i.e. a type that may or may not be there.

It is similar to std::optional<T> but lacks some functions and provides some others. It can be in one of two states: it contains a value of a certain type or it does not (it is "empty").

The storage itself is managed via the StoragePolicy. It must provide the following members:

Alias template type_safe::basic_optional::rebind

template <typename U>
using rebind = 'hidden';

Rebinds the current optional to the type U.

It will use ts::optional_storage_policy_for to determine whether a change of storage policy is needed. \notes If U is void, the result will be void as well. \notes Due to a specialization of ts::optional_storage_policy_for, if U is an optional itself, the result will be U, not an optional of an optional. \exclude target

Default constructor type_safe::basic_optional::basic_optional

(1)  basic_optional() noexcept = default;

(2)  basic_optional(nullopt_t) noexcept;

Effects: Creates it without a value.

Function template type_safe::basic_optional::basic_optional

template <typename T>
basic_optional(T&& value);

Effects: Creates it with a value by forwarding value.

Throws: Anything thrown by the constructor of value_type.

Requires: The create_value() function of the StoragePolicy must accept value.

Function template type_safe::basic_optional::basic_optional

template <typename T>
basic_optional(T&& value);

Effects: Creates it with a value by forwarding value.

Throws: Anything thrown by the constructor of value_type.

Requires: The create_value_explicit() function of the StoragePolicy must accept value.

Copy constructor type_safe::basic_optional::basic_optional

basic_optional(const basic_optional& other) = default;

Copy constructor.

Effects: If other does not have a value, it will be created without a value as well. If other has a value, it will be created with a value by copying other.value().

Throws: Anything thrown by the copy constructor of value_type if other has a value.

Notes: This constructor will not participate in overload resolution, unless the value_type is copy constructible.

Move constructor type_safe::basic_optional::basic_optional

basic_optional(basic_optional&& other) = default;

Move constructor.

Effects: If other does not have a value, it will be created without a value as well. If other has a value, it will be created with a value by moving other.value().

Throws: Anything thrown by the move constructor of value_type if other has a value.

Notes: other will still have a value after the move operation, it is just in a moved-from state.

Notes: This constructor will not participate in overload resolution, unless the value_type is move constructible.

Destructor type_safe::basic_optional::~basic_optional

~basic_optional() noexcept = default;

Destructor.

Effects: If it has a value, it will be destroyed.

Assignment operator type_safe::basic_optional::operator=

basic_optional& operator=(nullopt_t) noexcept;

Effects: Same as reset().

Assignment operator type_safe::basic_optional::operator=

template <typename T>
decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<T>(value)), *this) operator=(T&& value);

Effects: Same as emplace(std::forward<T>(t)).

Requires: The call to emplace() must be well-formed.

Assignment operator type_safe::basic_optional::operator=

basic_optional& operator=(const basic_optional& other) = default;

Copy assignment operator.

Effects: If other has a value, does something equivalent to emplace(other.value()) (this will always trigger the single parameter version). Otherwise will reset the optional to the empty state. \throws Anything thrown by the call to emplace(). \notes This operator will not participate in overload resolution, unless the value_type is copy constructible.

Assignment operator type_safe::basic_optional::operator=

basic_optional& operator=(basic_optional&& other) = default;

Move assignment operator.

Effects: If other has a value, does something equivalent to emplace(std::move(other).value()) (this will always trigger the single parameter version). Otherwise will reset the optional to the empty state.

Throws: Anything thrown by the call to emplace().

Notes: This operator will not participate in overload resolution, unless the value_type is copy constructible.

Function type_safe::swap

friend void swap(basic_optional& a, basic_optional& b) noexcept('hidden');

Effects: Swap. If both a and b have values, swaps the values with their swap function. Otherwise, if only one of them have a value, moves that value to the other one and makes the moved-from empty. Otherwise, if both are empty, does nothing. \throws Anything thrown by the move construction or swap.

Function type_safe::basic_optional::reset

void reset() noexcept;

Effects: Destroys the value by calling its destructor, if there is any stored. Afterwards has_value() will return false.

Function template type_safe::basic_optional::emplace

template <typename ... Args>
decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<Args>(args)...)) emplace(Args&&... args) noexcept('hidden');

Effects: First destroys any old value like reset(). Then creates the value by perfectly forwarding args... to the constructor of value_type.

Throws: Anything thrown by the constructor of value_type. If this function is left by an exception, the optional will be empty.

Notes: If the create_value() function of the StoragePolicy does not accept the arguments, this function will not participate in overload resolution. \synopsis_return void

Function template type_safe::basic_optional::emplace

template <typename Arg, typename = typename std::enable_if<detail::is_direct_assignable<decltype(std::declval<storage&>().get_value()), Arg&&>::value>::type>
decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<Arg>(arg))) emplace(Arg&& arg) noexcept('hidden');

Effects: If has_value() is false creates it by calling the constructor with arg perfectly forwarded. Otherwise assigns a perfectly forwarded arg to value(). \throws Anything thrown by the constructor or assignment operator chosen. \notes This function does not participate in overload resolution unless there is an operator= that takes arg without an implicit user-defined conversion and the create_value() function of the StoragePolicy accepts the argument. \synopsis_return void

Conversion operator type_safe::basic_optional::operator bool

operator bool() const noexcept;

Returns: The same as has_value().

Function type_safe::basic_optional::has_value

bool has_value() const noexcept;

Returns: Whether or not the optional has a value.

Function type_safe::basic_optional::value

(1)  decltype(std::declval<storage&>().get_value()) value() & noexcept;

(2)  decltype(std::declval<const storage&>().get_value()) value() const & noexcept;

(3)  decltype(std::declval<storage&&>().get_value()) value() && noexcept;

(4)  decltype(std::declval<const storage&&>().get_value()) value() const && noexcept;

Access to the stored value.

Returns: A reference to the stored value. The exact type depends on the StoragePolicy.

Requires: has_value() == true.

Function template type_safe::basic_optional::value_or

template <typename U>
decltype(std::declval<const storage&>().get_value_or(std::forward<U>(u))) value_or(U&& u) const &;

Returns: If it has a value, value(), otherwise u converted to the same type as value(). \requires u must be valid argument to the value_or() function of the StoragePolicy. \notes Depending on the StoragePolicy, this either returns a decayed type or a reference. \group value_or

Function template type_safe::basic_optional::value_or

(1)  template <typename U>
     decltype(std::declval<storage&&>().get_value_or(std::forward<U>(u))) value_or(U&& u) &&;

Function template type_safe::basic_optional::map

(1)  template <typename Func, typename ... Args>
     'hidden' map(Func&& f, Args&&... args) &;

(2)  template <typename Func, typename ... Args>
     'hidden' map(Func&& f, Args&&... args) const &;

(3)  template <typename Func, typename ... Args>
     'hidden' map(Func&& f, Args&&... args) &&;

(4)  template <typename Func, typename ... Args>
     'hidden' map(Func&& f, Args&&... args) const &&;

Maps an optional.

Effects: If the optional contains a value, calls the function with the value followed by the additional arguments perfectly forwarded.

Returns: A basic_optional rebound to the result type of the function, that is empty if *this is empty and contains the result of the function otherwise.

Requires: f must either be a function or function object of matching signature, or a member function pointer of the stored type with compatible signature.

Notes: Due to the way ts::basic_optional::rebind works, if the result of the function is void, map() will return void as well, and if the result of the function is an optional itself, map() will return the optional unchanged.


Comparison operator type_safe::operator==

template <class StoragePolicy>
bool operator==(const basic_optional<StoragePolicy>& lhs, nullopt_t);

Comparison of ts::basic_optional with ts::nullopt.

An optional is equal to ts::nullopt if it does not have a value. Nothing is less than ts::nullopt, it is only less than an optional, A optional compares equal to nullopt, when it does not have a value. A optional compares never less to nullopt, nullopt compares less only if the optional has a value. The other comparisons behave accordingly. \group optional_comp_null Optional null comparison \module optional

Comparison operator type_safe::operator==

(1)  template <class StoragePolicy>
     bool operator==(nullopt_t, const basic_optional<StoragePolicy>& rhs);

(2)  template <class StoragePolicy>
     bool operator!=(const basic_optional<StoragePolicy>& lhs, nullopt_t);

(3)  template <class StoragePolicy>
     bool operator!=(nullopt_t, const basic_optional<StoragePolicy>& rhs);

(4)  template <class StoragePolicy>
     bool operator<(const basic_optional<StoragePolicy>& lhs, nullopt_t);

(5)  template <class StoragePolicy>
     bool operator<(nullopt_t, const basic_optional<StoragePolicy>& rhs);

(6)  template <class StoragePolicy>
     bool operator<=(const basic_optional<StoragePolicy>& lhs, nullopt_t);

(7)  template <class StoragePolicy>
     bool operator<=(nullopt_t, const basic_optional<StoragePolicy>& rhs);

(8)  template <class StoragePolicy>
     bool operator>(const basic_optional<StoragePolicy>& lhs, nullopt_t);

(9)  template <class StoragePolicy>
     bool operator>(nullopt_t, const basic_optional<StoragePolicy>& rhs);

(10)  template <class StoragePolicy>
     bool operator>=(const basic_optional<StoragePolicy>& lhs, nullopt_t);

(11)  template <class StoragePolicy>
     bool operator>=(nullopt_t, const basic_optional<StoragePolicy>& rhs);

Optional value comparison [optional]

(1)  template <class StoragePolicy, typename U>
     bool operator==(const basic_optional<StoragePolicy>& lhs, const U& rhs);

(2)  template <class StoragePolicy, typename U>
     bool                                                                       operator==(const U& lhs, const basic_optional<StoragePolicy>& rhs);

(3)  template <class StoragePolicy, typename U>
     bool operator!=(const basic_optional<StoragePolicy>& lhs, const U& rhs);

(4)  template <class StoragePolicy, typename U>
     bool                                                                       operator!=(const U& lhs, const basic_optional<StoragePolicy>& rhs);

(5)  template <class StoragePolicy, typename U>
     bool operator<(const basic_optional<StoragePolicy>& lhs, const U& rhs);

(6)  template <class StoragePolicy, typename U>
     bool                                                                       operator<(const U& lhs, const basic_optional<StoragePolicy>& rhs);

(7)  template <class StoragePolicy, typename U>
     bool operator<=(const basic_optional<StoragePolicy>& lhs, const U& rhs);

(8)  template <class StoragePolicy, typename U>
     bool                                                                       operator<=(const U& lhs, const basic_optional<StoragePolicy>& rhs);

(9)  template <class StoragePolicy, typename U>
     bool operator>(const basic_optional<StoragePolicy>& lhs, const U& rhs);

(10)  template <class StoragePolicy, typename U>
     bool                                                                       operator>(const U& lhs, const basic_optional<StoragePolicy>& rhs);

(11)  template <class StoragePolicy, typename U>
     bool operator>=(const basic_optional<StoragePolicy>& lhs, const U& rhs);

(12)  template <class StoragePolicy, typename U>
     bool                                                                       operator>=(const U& lhs, const basic_optional<StoragePolicy>& rhs);

Compares a ts::basic_optional with a value.

An optional compares equal to a value if it has a value and the value compares equal. An optional compares less to a value if it does not have a value or the value compares less. A value compares less to an optional if the optional has a value and the value compares less than the optional. The other comparisons behave accordingly.

Value comparison is done by the comparison operator of the value_type, a function only participates in overload resolution if the value_type, has that comparison function.

Optional comparison [optional]

(1)  template <class StoragePolicy>
     bool operator==(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);

(2)  template <class StoragePolicy>
     bool operator!=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);

(3)  template <class StoragePolicy>
     bool operator<(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);

(4)  template <class StoragePolicy>
     bool operator<=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);

(5)  template <class StoragePolicy>
     bool operator>(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);

(6)  template <class StoragePolicy>
     bool operator>=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);

Compares two ts::basic_optional objects.

If lhs has a value, forwards to lhs.value() <op> rhs. Else forwards to nullopt <op> rhs.

Function template type_safe::with [optional]

template <class Optional, typename Func, typename ... Args>
void with(Optional&& opt, Func&& f, Args&&... additional_args);

With operation for ts::optional.

Effects: Calls the operator() of f passing it the value of opt and additional arguments, if it has a value. Otherwise does nothing.

Class template type_safe::direct_optional_storage [optional]

template <typename T>
class direct_optional_storage
{
public:
    using value_type = typename std::remove_cv<T>::type;
    
    using lvalue_reference = T&;
    
    using const_lvalue_reference = const T&;
    
    using rvalue_reference = T&&;
    
    using const_rvalue_reference = const T&&;
    
    template <typename U>
    using rebind = direct_optional_storage<U>;
    
    direct_optional_storage() noexcept;
    
    template <typename ... Args>
    typename std::enable_if<std::is_constructible<value_type, Args&&...>::value>::type create_value(Args&&... args);
    
    void create_value(const direct_optional_storage& other);
    void create_value(direct_optional_storage&& other);
    
    void create_value_explicit();
    
    void copy_value(const direct_optional_storage& other);
    void copy_value(const direct_optional_storage& other);
    
    void copy_value(direct_optional_storage&& other);
    void copy_value(direct_optional_storage&& other);
    
    void swap_value(direct_optional_storage& other);
    
    void destroy_value() noexcept;
    
    bool has_value() const noexcept;
    
    lvalue_reference get_value() & noexcept;
    const_lvalue_reference get_value() const & noexcept;
    rvalue_reference get_value() && noexcept;
    const_rvalue_reference get_value() const && noexcept;
    
    template <typename U, typename = typename std::enable_if<std::is_copy_constructible<value_type>::value&&std::is_convertible<U&&, value_type>::value>::type>
    value_type get_value_or(U&& u) const &;
    
    template <typename U>
    value_type get_value_or(U&& u) &&;
};

A StoragePolicy for ts::basic_optional that is similar to std::optional<T>'s implementation.

It uses std::aligned_storage and a bool flag whether a value was created.

Requires: T must not be a reference.

Default constructor type_safe::direct_optional_storage::direct_optional_storage

direct_optional_storage() noexcept;

Effects: Initializes it in the state without value.

Function template type_safe::direct_optional_storage::create_value

template <typename ... Args>
typename std::enable_if<std::is_constructible<value_type, Args&&...>::value>::type create_value(Args&&... args);

Effects: Calls the constructor of value_type by perfectly forwarding args. Afterwards has_value() will return true.

Throws: Anything thrown by the constructor of value_type in which case has_value() is still false. \requires has_value() == false. \notes This function does not participate in overload resolution unless value_type is constructible from args. \synopsis_return void

Function type_safe::direct_optional_storage::create_value

(1)  void create_value(const direct_optional_storage& other);

(2)  void create_value(direct_optional_storage&& other);

Effects: Creates a value by copy(1)/move(2) constructing from the value stored in other, if there is any.

Function template type_safe::direct_optional_storage::copy_value::copy_value

(1)  void copy_value(const direct_optional_storage& other);

(2)  void copy_value(const direct_optional_storage& other);

Effects: Copies the policy from other, by copy-constructing or assigning the stored value, if any.

Throws: Anything thrown by the copy constructor or copy assignment operator of other.

Function template type_safe::direct_optional_storage::copy_value::copy_value

(1)  void copy_value(direct_optional_storage&& other);

(2)  void copy_value(direct_optional_storage&& other);

Effects: Copies the policy from other, by move-constructing or assigning the stored value, if any.

Throws: Anything thrown by the move constructor or move assignment operator of other.

Function type_safe::direct_optional_storage::swap_value

void swap_value(direct_optional_storage& other);

Effects: Swaps the value with the value in other.

Function type_safe::direct_optional_storage::destroy_value

void destroy_value() noexcept;

Effects: Calls the destructor of value_type. Afterwards has_value() will return false.

Requires: has_value() == true.

Function type_safe::direct_optional_storage::has_value

bool has_value() const noexcept;

Returns: Whether or not there is a value stored.

Function type_safe::direct_optional_storage::get_value

(1)  lvalue_reference get_value() & noexcept;

(2)  const_lvalue_reference get_value() const & noexcept;

(3)  rvalue_reference get_value() && noexcept;

(4)  const_rvalue_reference get_value() const && noexcept;

Returns: A (const) (rvalue) reference to the stored value.

Requires: has_value() == true.

Function template type_safe::direct_optional_storage::get_value_or

template <typename U, typename = typename std::enable_if<std::is_copy_constructible<value_type>::value&&std::is_convertible<U&&, value_type>::value>::type>
value_type get_value_or(U&& u) const &;

Returns: Either get_value() or u converted to value_type.

Requires: value_type must be copy(1)/move(2) constructible and u convertible to value_type. \group get_value_or \param 1 \exclude

Function template type_safe::direct_optional_storage::get_value_or

(1)  template <typename U>
     value_type get_value_or(U&& u) &&;


Alias template type_safe::optional [optional]

template <typename T>
using optional = basic_optional<direct_optional_storage<T>>;

A ts::basic_optional that uses ts::direct_optional_storage<T>.

Alias template type_safe::optional_for [optional]

template <typename T>
using optional_for = basic_optional<direct_optional_storage<int>>::rebind<T>;

Uses ts::optional_storage_policy_for to select the appropriate ts::basic_optional.

By default, it uses ts::direct_optional_storage.

Notes: If T is void, optional_for will also be void.

Function template type_safe::make_optional [optional]

template <typename T>
optional<typename std::decay<T>::type> make_optional(T&& t);

Returns: A new ts::optional<T> storing a copy of t.

Function template type_safe::make_optional

template <typename T, typename ... Args>
optional<T> make_optional(Args&&... args);

Returns: A new ts::optional<T> with a value created by perfectly forwarding args to the constructor. \module optional